package com.study.mike.model.dto;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.study.mike.common.annotation.Sensitive;
import com.study.mike.common.enums.SensitiveEnum;
import com.study.mike.common.utils.SensitiveUtil;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.Objects;


/**
 * @author kh
 */

@NoArgsConstructor
@AllArgsConstructor
public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {

    /**
     * 脱敏类型
     */
    private SensitiveEnum sensitiveEnum;
    /**
     * 前几位不脱敏
     */
    private Integer prefixNoMaskLen;
    /***
     * 最后几位不脱敏
     */
    private Integer suffixNoMaskLen;
    /**
     * 替换的数据
     */
    private String symbol;

    @Override
    public void serialize(final String origin, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException {
        if (StringUtils.isNotBlank(origin) && null != sensitiveEnum) {
            switch (sensitiveEnum) {
                case CUSTOMER:
                    jsonGenerator.writeString(SensitiveUtil.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, symbol));
                    break;
                case NAME:
                    jsonGenerator.writeString(SensitiveUtil.hideChineseName(origin));
                    break;
                case ID_CARD:
                    jsonGenerator.writeString(SensitiveUtil.hideIDCard(origin));
                    break;
                case PHONE:
                    jsonGenerator.writeString(SensitiveUtil.hidePhone(origin));
                    break;
                case EMAIL:
                    jsonGenerator.writeString(SensitiveUtil.hideEmail(origin));
                    break;
                default:
                    throw new IllegalArgumentException("unknown privacy type enum " + sensitiveEnum);
            }
        }
    }

    @Override
    public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
                                              final BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
                if (sensitive == null) {
                    sensitive = beanProperty.getContextAnnotation(Sensitive.class);
                }
                if (sensitive != null) {
                    return new SensitiveSerializer(sensitive.type(), sensitive.prefixNoMaskLen(),
                            sensitive.suffixNoMaskLen(), sensitive.symbol());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }

}